from strategy.StrategyTemplate import StrategyTemplate
from strategy import strategy_filter
from utils.db import DbHandler
from strategy.pro_strategy.pro_strategy_common import threegetvegetable_column


class ThreeGetvegetable(StrategyTemplate):
    """
     启四的年化收益27%三要素策略
     三要素评分 = 溢价率×100+剩余年限-到期收益率×100，越低越好
     莫非是银行债被排除了?
     import qstock as qs
     筛选方法:

         溢价率 ≦ 30%，到期收益率 > 0，并排除掉已发强赎公告的可转债
     买入方法:

         平均买入排名前 10 或者前 20 的转债
     卖出方法:

         每月第一个交易日轮动，公告强赎后第5个交易日卖出
     详细介绍: 三要素策略

     筛选总数: 11

     """
    def __init__(self):
        super(self.__class__, self).__init__()
        self.strategy_name = "启四老三低策略"
        self.strategy_descrption = "按涨幅排序"

    def run(self):
        # 基础过滤，过滤掉新债、强赎、EB
        self.data = strategy_filter.filter_base(self.data)
        # 溢价率小于等于30
        self.data = self.data.loc[self.data['溢价率'] <= 30]
        self.data = self.data.loc[self.data['到期税前收益'] > 0]

        self.data['评分'] = self.data['溢价率'] + self.data['剩余年限'] - self.data['到期税前收益']
        self.data = round(self.data.sort_values(by='评分', ascending=True),3)
        self.data = self.data[['转债名称', '转债代码', '现价', '涨跌幅', '溢价率', '转股价值', '剩余年限', '剩余规模', '评分', '行业', '正股波动率', '基金持仓']]

    def api(self, size=10):

        db = DbHandler()
        db.create_session()
        super(self.__class__, self).api(db=db)

        self.data = strategy_filter.filter_st_bond(self.data)
        self.data = strategy_filter.filter_new_bond(self.data)

        # 溢价率小于等于30
        self.data = self.data.loc[self.data['premium_rt'] <= 30]
        self.data = self.data.loc[self.data['ytm_rt'] > 0]

        self.data['score'] = self.data['premium_rt'] + self.data['year_left'] - self.data['ytm_rt']
        self.data = round(self.data.sort_values(by='score', ascending=True), 3)
        self.data['fund_rt'] = self.data['fund_rt'].fillna(0)

        pd_bond_data = self.data[threegetvegetable_column]
        self.db.close_session()
        return pd_bond_data

if __name__ == '__main__':
    ins = ThreeGetvegetable()
    ins.topN = 20
    ins.test()

